package cz.worktracker.controller;

import cz.worktracker.enums.DataSetsEnum;
import javax.faces.model.DataModel;

/**
 * Paginator class.
 * Created by the original class from examples of the Netbeans program.
 * Paging implementation.
 * @author pagac
 */
public abstract class AbstractPaginator {
    
    private int pageSize;
    private int page;
    private int itemsPerPage;
    private DataSetsEnum DSEnum;


    /**
     * Constructor
     * @param pageSize Size of returned data set to view.
     */
    public AbstractPaginator( int pageSize ) {
        this.pageSize = pageSize;
    }


    /**
     * Method return overall items count for current conditions.
     *
     * Eg. Query return overall data set with items count greater
     * than pageSize is (items per page).
     *
     * items count = 52 (this is returned by getItemsCount)
     * pageSize = 25
     *
     * So it lead to 3 pages (25 + 25 + 2).
     *
     * @return Overall items count.
     */
    public abstract int getItemsCount();


    /**
     * Method create JSF DataModel for ui component that holds data.
     * @return DataModel object.
     */
    public abstract DataModel createPageDataModel();


    /**
     * Method returns index of first item on selected page.
     * @return Index of first item on page.
     */
    public int getPageFirstItem() {
        return page * pageSize;
    }


    /**
     * Returns last item on page.
     * @return Index of last item on page.
     */
    public int getPageLastItem() {
        int i = getPageFirstItem() + pageSize - 1;
        int count = getItemsCount() - 1;
        
        if( i > count ) {
            i = count;
        }

        if( i < 0 ) {
            i = 0;
        }

        return i;
    }


    /**
     * Method return boolean value.
     * Eg. If current page displays items 25-30 from 32 overall.
     * Then there is next page.
     * @return True if there is next page. False otherwise.
     */
    public boolean isHasNextPage() {
        return (( page + 1 ) * pageSize + 1 <= getItemsCount());
    }


    /**
     * Increments page counter by one.
     */
    public void nextPage() {
        if( isHasNextPage() ) {
            page++;
        }        
    }

    /**
     * Sets counter to maximum.
     */
    public void lastPage() {
        if( isHasNextPage() ) {
            page = (int) getItemsCount() / getPageSize();
        }
    }


    /**
     * Returns boolean value.
     * @return True if pages counter is greater than 0. Otherwise false.
     */
    public boolean isHasPreviousPage() {
        return page > 0;
    }


    /**
     * Decrement page counter by one.
     */
    public void previousPage() {
        if (isHasPreviousPage()) {
            page--;
        }
    }

    /**
     * Sets counter to minimum.
     */
    public void firstPage() {
        if( isHasPreviousPage() ) {
            page = 0;
        }
    }


    /**
     * Checks if less records per row means nothing to show.
     */
    public boolean isRemainsSomething() {
        if( (getPageSize() - DSEnum.ITEMS_PER_PAGE_INCREMENT.getValue()) + 1 < DSEnum.ITEMS_PER_PAGE_DEFAULT.getValue() ) {
            return false;
        } else {
            return true;
        }
    }


    /**
     * Returns true, if adding more items per page is still reasonable.
     * @return True if adding is safe. False otherwise.
     */
    public boolean isMoreSafe() {
        if( getTotalPageCount() >= 1 ) {
            return true;
        } else {
            return false;
        }
    }


    /**
     * Returns current pageSize().
     * @return int
     */
    public int getPageSize() {
        return pageSize;
    }


    /**
     * Returns current page.
     * @return int
     */
    public int getActualPage() {
        return page;
    }


    /**
     * Returns page count.
     * @return int
     */
    public int getTotalPageCount() {
        return  (int) Math.ceil(getItemsCount() / getPageSize());
    }

    public int getItemsPerPage() {
        return itemsPerPage;
    }

    public void setItemsPerPage(int itemsPerPage) {
        this.itemsPerPage = itemsPerPage;
    }
 
}
